﻿using System;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using log4net;
using PagedList;
using QAS.Nekorama.Filters;
using QAS.Nekorama.Models;

namespace QAS.Nekorama.Controllers
{
    /// <summary>
    ///タグモデルのコントローラー
    /// </summary>
    [InitializeSimpleMembership]
    [HandleError]
    public class TagController : Controller
    {
        private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private readonly Entities db = new Entities();

        /// <summary>
        ///  Indexビューからパラメーターをもらい、モデルに相応なデータを取り出ます。
        ///  ビュー含有:　Index.cshtml
        ///  アクション含有: Index
        /// </summary>
        /// <param name="currentFilter">現在なフィルタストリング</param>
        /// <param name="searchTagString">検索キーワード</param>
        /// <param name="page">ページ数</param>
        /// <returns>Indexビュー</returns>
        public ActionResult Index(string currentFilter, string searchTagString, int? page)
        {
            _log.Debug("Start action " + MethodBase.GetCurrentMethod().Name);
            try
            {
                //ページング中に現在なフィルタに検索キーワードをします。そして、ページが再表示される時テキストボックスに検索キーワードを戻します。
                if (searchTagString != null)
                {
                    //新しい検索キーワードがビューから送られます。他の結果ページを表示するためページを１に再設定します。
                    searchTagString = searchTagString.Trim();
                    page = 1;
                }
                else
                {
                    //ページング
                    searchTagString = currentFilter;
                }
                ViewBag.CurrentFilter = searchTagString;

                //データベースからタグを取り出ます。
                IQueryable<Tag> taglist = from t in db.Tags orderby t.TagName select t;

                //タグ名で探します。
                if (!String.IsNullOrEmpty(searchTagString))
                {
                    taglist = taglist.Where(t => t.TagName.Contains(searchTagString));
                }
                int pageNumber = (page ?? 1);
                _log.Debug("End action " + MethodBase.GetCurrentMethod().Name);
                return View(taglist.ToPagedList(pageNumber, 40));
            }
            catch (ArgumentNullException exception)
            {
                _log.Error(
                    string.Format("An {0} exception has occured at {1} action. ", exception.GetType(),
                        MethodBase.GetCurrentMethod().Name) + exception.Message, exception);
                return View("Error", new HandleErrorInfo(exception, "Tag", "Index"));
            }
            catch (InvalidOperationException exception)
            {
                _log.Error(
                    string.Format("An {0} exception has occured at {1} action. ", exception.GetType(),
                        MethodBase.GetCurrentMethod().Name) + exception.Message, exception);
                return View("Error", new HandleErrorInfo(exception, "Tag", "Index"));
            }
            catch (Exception exception)
            {
                _log.Fatal(
                    string.Format("A fatal exception has occured at {0} action ", MethodBase.GetCurrentMethod().Name) +
                    exception.Message, exception);
                throw;
            }
        }
        /// <summary>
        /// 使用の後、エンティティのオブジェクトを削除します。
        /// </summary>
        /// <param name="disposing">削除するかどうか</param>
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
        /// <summary>
        /// アクションで処理されない例外を処理します。
        /// </summary>
        /// <param name="filterContext">例外のコンテキスト</param>
        protected override void OnException(ExceptionContext filterContext)
        {
            filterContext.Exception = new Exception("");
            filterContext.ExceptionHandled = true;
            filterContext.Result = View("Error", new HandleErrorInfo(filterContext.Exception, "Question", "Details"));
        }
    }
}